using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Framework.Event{

    
    public class Event:Framework.Base.BaseObject{
        private readonly Dictionary<string, Signal> m_eventDict = new Dictionary<string, Signal>();
        
        // 添加事件监听
        public void AddListener(string eventName,FuncDelegate func){
            Signal signal;
            if(!this.m_eventDict.TryGetValue(eventName, out signal)){
                signal = Base.PoolMgr.Create<Signal>();
                this.m_eventDict[eventName] = signal;
            }
            signal.On(func);
        }

        public void AddListener<A>(string eventName, FuncDelegate<A> func){
            Signal signal;
            if(!this.m_eventDict.TryGetValue(eventName, out signal)){
                signal = Base.PoolMgr.Create<Signal<A>>();
                this.m_eventDict[eventName] = signal;
            }
            ((Signal<A>)signal).On(func);
        }

        public void AddListener<A,B>(string eventName, FuncDelegate<A,B> func){
            Signal signal;
            if(!this.m_eventDict.TryGetValue(eventName, out signal)){
                signal = Base.PoolMgr.Create<Signal<A,B>>();
                this.m_eventDict[eventName] = signal;
            }
            ((Signal<A,B>)signal).On(func);
        }

        public void AddListener<A,B,C>(string eventName, FuncDelegate<A,B,C> func){
            Signal signal;
            if(!this.m_eventDict.TryGetValue(eventName, out signal)){
                signal = Base.PoolMgr.Create<Signal<A,B,C>>();
                this.m_eventDict[eventName] = signal;
            }
            ((Signal<A,B, C>)signal).On(func);
        }


        public void RemoveListener(string eventName, FuncDelegate func){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                signal.Off(func);
                if(signal.isEmpty()){
                    Base.PoolMgr.Recycle(signal);
                    this.m_eventDict.Remove(eventName);
                }
            }
        }
        
        public void RemoveListener<A>(string eventName, FuncDelegate<A> func){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A>)signal).Off(func);
                if(signal.isEmpty()){
                    Base.PoolMgr.Recycle(signal);
                    this.m_eventDict.Remove(eventName);
                }
            }
        }
        

        public void RemoveListener<A,B>(string eventName, FuncDelegate<A,B> func){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A,B>)signal).Off(func);
                if(signal.isEmpty()){
                    Base.PoolMgr.Recycle(signal);
                    this.m_eventDict.Remove(eventName);
                }
            }
        }

        public void RemoveListener<A,B,C>(string eventName, FuncDelegate<A,B,C> func){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A,B,C>)signal).Off(func);
                if(signal.isEmpty()){
                    Base.PoolMgr.Recycle(signal);
                    this.m_eventDict.Remove(eventName);
                }
            }
        }

        public void Emit(string eventName){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                signal.Emit();
            }
        }

        public void Emit<A>(string eventName, A a){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A>)signal).Emit(a);
            }
        }


        public void Emit<A, B>(string eventName, A a, B b){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A, B>)signal).Emit(a,b);
            }
        }

        public void Emit<A, B, C>(string eventName, A a, B b, C c){
            Signal signal;
            if(this.m_eventDict.TryGetValue(eventName, out signal)){
                ((Signal<A, B, C>)signal).Emit(a,b, c);
            }
        }

        //  移除某个对象的全部事件监听
        public void RemoveObj(object obj){
            foreach(var pair in this.m_eventDict){
                var signalObj = pair.Value;
                signalObj.RemoveObj(obj);
                if(signalObj.isEmpty()){
                    Base.PoolMgr.Recycle(signalObj);
                    this.m_eventDict.Remove(pair.Key);
                }
            }
        }

        public void Clear(){
            foreach(var pair in this.m_eventDict){
                Base.PoolMgr.Recycle(pair.Value);
                this.m_eventDict.Remove(pair.Key);
            }
        }
    }
}